package eu;

import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import eu.common.config.ConfigEngine;
import eu.common.toolkits.ResourceUtil;

/**
 * 应用上下文，包括一些常用配置，坏境变量等。有三个来源，serverContext.xml配置文件、EnvSetFilter、
 * StartupListener
 * 
 * @author WZZ
 * 
 */
public abstract class AppContext {

	private static Map<String, String> config = new Hashtable<String, String>();

	/**
	 * 初始化Context
	 */
	public static void loadConfig() {
		Map<String, String> unsolved = new HashMap<String, String>();
		ConfigEngine engine = ConfigEngine.getEngine(
				ConfigEngine.EngineType.XMLEngine,
				ResourceUtil.getResourcePath("eu.context.xml"), "UTF-8");
		// 解析配置文件
		for (String key : engine.getSubNames("/context/config")) {
			String value = engine.getValue("/context/config/" + key);
			if (value == null)
				continue;
			if (value.contains("${")) {
				praseVar(config, unsolved, key, value);
			} else {
				config.put(key, value);
			}
		}
		int size = unsolved.size();
		String[] keys = {};
		while(unsolved.size() > 0) {
			for (String key : unsolved.keySet().toArray(keys)) {
				praseVar(config, unsolved, key, unsolved.get(key));
			}
			if (unsolved.size() == size) {
				break;
			}
			size = unsolved.size();
		}
	}

	private static boolean praseVar(Map<String, String> config,
			Map<String, String> unsolved, String key, String express) {
		String reg = "\\$\\{[^\\{\\}]+\\}";
		Pattern pattern = Pattern.compile(reg);
		Matcher match = pattern.matcher(express);
		while (match.find()) {
			String name = match.group();
			name = name.substring(2, name.length() - 1).trim();
			if (containsConfig(name)) {
				express = express.replace("${" + name + "}", config.get(name));
			}
		}
		if (express.contains("${")) {
			if (!unsolved.containsKey(key))
				unsolved.put(key, express);
			return false;
		} else {
			config.put(key, express);
			if (unsolved.containsKey(key))
				unsolved.remove(key);
			return true;
		}
	}

	public static String getConfig(String name) {
		return config.get(name);
	}

	public static boolean containsConfig(String name) {
		return config.containsKey(name);
	}
	
	public static String putConfig(String key, String value) {
		return config.put(key, value);
	}

}
